package org.paysim.payment.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.paysim.annotation.Channel;
import org.paysim.constant.UnionConfig;
import org.paysim.payment.model.PaymentCancelRequest;
import org.paysim.payment.model.PaymentCancelResponseData;
import org.paysim.payment.model.PaymentInitiateRequest;
import org.paysim.payment.service.IPaymentService;
import org.paysim.util.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.SDKConfig;

import jakarta.validation.Valid;

@Channel("unionPay")
@Service
public class UnionPayService implements IPaymentService {
    @Value("${unionPay.notify.url:}")
    private String notify_url;
    
    private static final Logger logger = LoggerFactory.getLogger(UnionPayService.class);

    @Override
    public String initiatePayment(PaymentInitiateRequest paymentInitiateRequest) {
        Map<String, String> requestData = new HashMap<String, String>();
        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
        requestData.put("version", UnionConfig.version);              //版本号，全渠道默认值
        requestData.put("encoding", UnionConfig.encoding_UTF8);       //字符集编码，可以使用UTF-8,GBK两种方式
        requestData.put("signMethod", "01");                          //签名方法，只支持 01：RSA方式证书加密
        requestData.put("txnType", "01");                             //交易类型 ，01：消费
        requestData.put("txnSubType", "01");                          //交易子类型， 01：自助消费
        requestData.put("bizType", "000201");                         //业务类型，B2C网关支付，手机wap支付
        //渠道类型，这个字段区分B2C网关支付和手机wap支付；07：PC,平板  08：手机
        // TODO 暂时固定为PC
        requestData.put("channelType", "08"); 
//        if(product.getPayWay()==PayWay.MOBILE.getCode()){//手机支付
//            requestData.put("channelType", "08");  
//        }else{//PC支付
//            requestData.put("channelType", "07");
//        }
        //前台回调地址(自定义)
        String frontUrl = "http://rocket-server.liujiajin.com.cn:8080";
        requestData.put("frontUrl", frontUrl);
        /***商户接入参数 测试账号***/
        requestData.put("merId", UnionConfig.merId);                  //商户号码，请改成自己申请的正式商户号或者open上注册得来的777测试商户号
        requestData.put("accessType", "0");                           //接入类型，0：直连商户 
        requestData.put("orderId", paymentInitiateRequest.getOrderId());          //商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则     
        requestData.put("txnTime", UnionConfig.getCurrentTime());     //订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
        requestData.put("currencyCode", "156");                       //交易币种（境内商户一般是156 人民币）
        requestData.put("txnAmt", CommonUtils.subZeroAndDot(paymentInitiateRequest.getTotalAmount()));             //交易金额，单位分，不要带小数点
        //这里组织穿透数据 业务以及交易类型(使用json数据报错)
        requestData.put("reqReserved","自定义参数");       //请求方保留域，如需使用请启用即可；透传字段（可以实现商户自定义参数的追踪）本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字节       
        requestData.put("backUrl", notify_url);
        String form = "";
        try {
        Map<String, String> submitFromData = AcpService.sign(requestData,UnionConfig.encoding_UTF8);  //报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
        
        String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl();  //获取请求银联的前台地址：对应属性文件acp_sdk.properties文件中的acpsdk.frontTransUrl
        form = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData,UnionConfig.encoding_UTF8);   //生成自动跳转的Html表单
        } catch (Exception e) {
         // TODO Auto-generated catch block
           e.printStackTrace();
        }
        logger.info("打印请求HTML，此为请求报文，为联调排查问题的依据：{}",form);
        return form;
    }

    @Override
    public void notifyPayment(Map<String, String> params) {
        // TODO Auto-generated method stub

    }

    @Override
    public PaymentCancelResponseData cancelPayment(@Valid PaymentCancelRequest paymentCancelRequest) {
        // TODO Auto-generated method stub
        return null;
    }

}
